home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / MacGnuGo 0.5e / gnugo.src / matchpat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-01  |  5.1 KB  |  174 lines  |  [TEXT/R*ch]

  1. #include "comment.header"
  2.  
  3. #define EMPTY 0
  4. #define MAXPC 16
  5. #define abs(x) ((x) < 0 ? -(x) : (x))
  6. #define line(x) (abs(x - 9))
  7.  
  8. extern unsigned char p[19][19];
  9. extern int currentStone, opposingStone, MAXX, MAXY;
  10. extern int lib;
  11. extern void countlib(int,int,int);
  12. extern int fiot(int,int,int);        /* filling in safe territory? */
  13. extern int fieldval(int,int);
  14.  
  15. int selpat, selv;
  16.  
  17. /* match pattern and get next move */
  18. int matchpat(int m, int n, int *i, int *j, int *val)
  19. {
  20.   struct patval {
  21.     int x;    /* pattern x, y coordinate */
  22.     int y;
  23.     int att;    /* pattern attribute */
  24.       /* att = 0 - empty, 1 - your piece, 2 - my piece, 3 - my next move */
  25.       /* 4 - empty on edge, 5 - your piece on edge, 6 - my piece on edge */
  26.       /* 7 - not my piece, 8 - not your piece */
  27.   };
  28.  
  29.   struct pattern {
  30.     struct patval patn[MAXPC];        /* pattern */
  31.     int patlen;        /* number of pieces in pattern */
  32.     int trfno;        /* number of transformations to try, 4 or 8 */
  33.     int patwt;        /* pattern value */
  34.   };
  35.   
  36. #include "patterns.c"    /* patterns in a seperate file */
  37.   
  38.   static int trf [8][2][2] = {        /* transformation matrice */
  39.     {{ 1,  0}, { 0,  1}},  /* no transformation */
  40.     {{ 1,  0}, { 0, -1}},  /* invert */
  41.     {{ 0,  1}, {-1,  0}},  /* rotate 90 */
  42.     {{ 0, -1}, {-1,  0}},  /* rotate 90 and invert */
  43.     {{-1,  0}, { 0,  1}},  /* flip left */
  44.     {{-1,  0}, { 0, -1}},  /* flip left and invert */
  45.     {{ 0,  1}, { 1,  0}},  /* rotate 90 and flip left */
  46.     {{ 0, -1}, { 1,  0}}   /* rotate 90, flip left and invert */
  47.   };
  48.  
  49.   int k, my, nx, l, r, cont;
  50.   int ti, tj, tval;
  51.   int fv;
  52.   
  53.   *i = -1;   *j = -1;   *val = -1;        /* initialize */
  54.   ti = tj = 0;  fv = 0;
  55.   for (r = 0; r < PATNO; r++)
  56.     if (pat[r].patwt + 10  > *val) {            /* try each pattern */
  57.     /* try each orientation transformation */
  58.       for (l = 0; l < pat[r].trfno; l++) {
  59.     k = 0;                    /* k = pattern point index */
  60.     cont = 1;                /* set pattern ok flag */
  61.     while ((k != pat[r].patlen) && cont) {    /* match each point */
  62.       /* transform pattern to a real coordinate */
  63.       nx = n + trf[l][0][0] * pat[r].patn[k].x
  64.           + trf[l][0][1] * pat[r].patn[k].y;
  65.       my = m + trf[l][1][0] * pat[r].patn[k].x
  66.           + trf[l][1][1] * pat[r].patn[k].y;
  67.         
  68.       if ((my < 0) || ( my > MAXY - 1) || (nx < 0) || (nx > MAXX - 1)) {
  69.         cont = 0;             /* it's outside the board */
  70.         break;
  71.       }
  72.       switch (pat[r].patn[k].att) {
  73.         case 0 : if (p[my][nx] == EMPTY)        /* open */
  74.                    break;
  75.                  else {
  76.                cont = 0;    /* clear ok flag if not EMPTY */
  77.                  }
  78.              break;
  79.         case 1 : if (p[my][nx] == opposingStone)     /* your piece */
  80.                    break;
  81.                  else {
  82.                cont = 0;
  83.                  }
  84.              break;
  85.         case 2 : if (p[my][nx] == currentStone)     /* my piece */
  86.                    break;
  87.                  else {
  88.                cont = 0;
  89.                  }
  90.              break;
  91.         case 3 : if (p[my][nx] == EMPTY) {        /* move here */
  92.                lib = 0;             /* open for move */
  93.                countlib(my, nx, currentStone);    /* check liberty */
  94.                if (lib > 1 && !fiot(my,nx,3)) {
  95.                  ti = my;            /* move o.k. */
  96.                  tj = nx;
  97.              fv = fieldval(my,nx);
  98.                } else {
  99.                  cont = 0;        /* suicide not allowed */
  100.                }
  101.                  } else {
  102.                cont = 0;
  103.                  }
  104.              break;
  105.         case 4 : if ((p[my][nx] == EMPTY)        /* open on edge */
  106.              && ((my == 0) || (my == MAXY - 1) ||
  107.                  (nx == 0) || (nx == MAXX - 1)))
  108.                    break;
  109.                  else {
  110.                cont = 0;
  111.                  }
  112.              break;
  113.         case 5 : if ((p[my][nx] == opposingStone) /* your piece on edge */
  114.              && ((my == 0) || (my == MAXY - 1) ||
  115.                  (nx == 0) || (nx == MAXX - 1)))
  116.                    break;
  117.                  else {
  118.                cont = 0;
  119.                  }
  120.              break;
  121.         case 6 : if ((p[my][nx] == currentStone)    /* my piece on edge */
  122.              && ((my == 0) || (my == MAXY - 1) ||
  123.                  (nx == 0) || (nx == MAXX - 1)))
  124.                    break;
  125.                  else {
  126.                cont = 0;
  127.                  }
  128.              break;
  129.         case 7 : if (p[my][nx] == opposingStone || p[my][nx] == EMPTY)
  130.                    break;                /* not my piece */
  131.                  else {
  132.                cont = 0;
  133.                  }
  134.              break;
  135.         case 8 : if (p[my][nx] == currentStone || p[my][nx] == EMPTY)
  136.                    break;                /* not your piece */
  137.                  else {
  138.                cont = 0;
  139.                  }
  140.              break;
  141.       }    /* done with switch on type */
  142.       ++k;
  143.     }    /* next point in pattern */
  144.  
  145.     if (cont) {            /* it matches pattern */
  146.         tval = pat[r].patwt - fv;
  147.         if ((r >= 8) && (r <= 13)) { /* patterns for expand region */
  148.         if (line(ti) > 7)    /* penalty on line 1, 2 */
  149.           tval--;
  150.         else
  151.           if ((line(ti) == 6) || (line(ti) == 7))
  152.             tval++;        /* reward on line 3, 4 */
  153.         
  154.         if (line(tj) > 7)     /* penalty on line 1, 2 */
  155.           tval--;
  156.         else
  157.           if ((line(tj) == 6) || (line(tj) == 7))
  158.             tval++;        /* reward on line 3, 4 */
  159.         }
  160.         if (tval > *val) {
  161.         *val = tval;
  162.         *i = ti;
  163.         *j = tj;
  164.         selpat = 1000 + r; selv = fv;
  165.         }
  166.     }    /* found match */
  167.       }        /* each orientation */
  168.     }        /* each pattern */
  169.  
  170.   if (*val > 0) return 1;    /* pattern matched */
  171.   else          return 0;    /* all matches failed */
  172. }
  173. /* end matchpat */
  174.